package Controllers;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Observable;
import java.util.Observer;
import Entities.RegisterEntity;
import Entities.WindowClose;
import GUI.RegisterGUI;
import Server.RsWraper;
import Server.Tuple;

/**
 * RegisterController class implements Validate interface.
 * this class registers new users into the database.
 * @author Ofek-az
 *
 */
public class RegisterController implements Validate,Observer{
	/**
	 * This is the register boundary.
	 */
	private RegisterGUI registerGui;
	/**
	 * This is the register entity.
	 */
	private RegisterEntity registerEnt;
	/**
	 * This is the previous window (login window).
	 */
	private LoginController prev;
	
	/** The tuples. */
	private ArrayList<Tuple> tuples;
	
	/** The operation. */
	private int operation=0;
	
	
	/**
	 * This is the constructor.
	 *
	 * @param registerGui This is the register boundary.
	 * @param registerEnt This is the register entity.
	 */
	public RegisterController(RegisterGUI registerGui,RegisterEntity registerEnt) {
		this.registerGui = registerGui;
		this.registerEnt = registerEnt;
		ClientController.setObserver(this);
		this.registerGui.addWindowListener(new WindowClose());
		this.registerGui.addRegisterActionListener(new RegisterListener() );
		this.registerGui.addBackActionListener(new BackListener());
		addLivingAreasToCb();
		this.registerGui.setVisible(true);
	}
	
	/**
	 * Adds the living areas to the combo box.
	 */
	private void addLivingAreasToCb()
	{
		String query = "SELECT livingareas.name FROM livingareas";
		try {
			ClientController.observableClient.sendToServer(query);
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
	}
	
	/**
	* RegisterListener class implements ActionListener interface.
	* this class controls the register button.
	 * @author Ofek-az
	 *
	 */
	class RegisterListener implements ActionListener
	{

		/* (non-Javadoc)
		 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
		 */
		@Override
		public void actionPerformed(ActionEvent e) {
			if(validateInput())
			{
				registerEnt.setUid(registerGui.getUidTf());
				registerEnt.setPass(registerGui.getPassTf());
				registerEnt.setName(registerGui.getNameTf());
				registerEnt.setEmail(registerGui.getEmailTf());
				int birthyear=Integer.valueOf((String) registerGui.getDobTf().subSequence(6,10));
				int currentyear=Integer.valueOf((new Date()).getYear())+1900;
				registerEnt.setAge(currentyear-birthyear);
				registerEnt.setPosition(registerGui.getPosTf());
				registerEnt.setPhoneNumber(registerGui.getPhoneTf());
				registerEnt.setLivingArea((String) registerGui.getLaCb().getSelectedItem());
				String regQuery="INSERT INTO employees (`eid`, `position`) VALUES ('"+registerEnt.getUid()+"', '"+registerEnt.getPosition()+"')";	//register new employee (in employees table) query.
				
				try {
					ClientController.observableClient.sendToServer(regQuery);
					
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				
				
			}
			
		}
		
	}
	/**
	* BackListener class implements ActionListener interface.
	* this class controls the back button.
	 * @author Ofek-az
	 *
	 */
	class BackListener implements ActionListener
	{

		/* (non-Javadoc)
		 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
		 */
		@Override
		public void actionPerformed(ActionEvent e) {
			registerGui.dispose();
			prev.getLoginGui().setVisible(true);
			ClientController.setObserver(prev);
		}

	}
	
	/* (non-Javadoc)
	 * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
	 */
	@Override
	public void update(Observable arg0, Object arg) {
		String msg = (String) arg.toString();
		if(msg.equals("error"))
			registerGui.displayWarningMessage("The same employee is already exists");
		else
			if(operation==0)
			{
				tuples=new ArrayList<Tuple>();
				Tuple tuple=new Tuple();
				tuple.put("NAME"," ");		//puts a blank option in the first cell
				tuples.add(tuple);
				tuples.addAll(((RsWraper)arg).getRows());		//appends all products list
				for(int i=0;i<tuples.size();i++)
				{
					registerGui.getLaCb().addItem(tuples.get(i).get("NAME"));
				}
				
				operation=1;
			}
			else if(operation==1)
			{
				String regQuery="INSERT INTO users (`uid`, `password`, `name`, `livingArea`, `age`, `phoneNumber`, `email`, `loginStatus`) VALUES ('"+registerEnt.getUid()+"', '"+registerEnt.getPass()+"', '"+registerEnt.getName()+"', '"+registerEnt.getLivingArea()+"','"+registerEnt.getAge()+"', '"+registerEnt.getPhoneNumber()+"', '"+registerEnt.getEmail()+"', '0')";	//register new employee(in users table) query.
				try {
					ClientController.observableClient.sendToServer(regQuery);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				operation=2;
			}
			else
			{
				registerGui.displayMessage("Register succeded");
				operation=1;
			}
	}
	/*
	 * (non-Javadoc)
	 * 
	 * @see Controllers.Validate#validateInput()
	 */
	@Override
	public boolean validateInput() {
		String id=registerGui.getUidTf();
		String pass=registerGui.getPassTf();
		String name=registerGui.getNameTf();
		String email=registerGui.getEmailTf();
		String dob=registerGui.getDobTf();
		String position=registerGui.getPosTf();
		String phoneNumber=registerGui.getPhoneTf();
		String livingarea=(String)registerGui.getLaCb().getSelectedItem();
		String[] pos={"MM","ME","CRE","SM"};
		if(id.equals("")||pass.equals("")||name.equals("")||email.equals("")||dob.equals("")||position.equals("")||phoneNumber.equals("")||livingarea.equals(" "))
		{
			registerGui.displayWarningMessage("Please fill all the missing fields.");
			return false;
		}
		else
		{
			if(!isValidDate(registerGui.getDobTf()))
			{
				registerGui.displayWarningMessage("Error:illeagel date entered");
				return false;
			}
			if(Arrays.binarySearch(pos, 0, pos.length, position)==0)
			{
				registerGui.displayWarningMessage("Position field must be : ME,MM,CRE or SM");
				return false;
			}
			try
			{
				Integer.parseInt(id);
			}
			catch (NumberFormatException e)
			{
				registerGui.displayWarningMessage("Error:illeagel characters in id field.");
				return false;
			}
			try
			{
				Integer.parseInt(phoneNumber);
			}
			catch (NumberFormatException e)
			{
				registerGui.displayWarningMessage("Error:illeagel characters in phone number field.");
				return false;
			}
			
			return true;
		}
	}

	/**
	 * Sets the previous controller.
	 *
	 * @param prev the new previous controller
	 */
	public void setPrev(LoginController prev) {
		this.prev = prev;
	}
	
	/**
	 * Checks if is valid date.
	 *
	 * @param date the date
	 * @return true, if is valid date
	 */
	public boolean isValidDate(String date)
	{
		GregorianCalendar cal = new GregorianCalendar();
		cal.setLenient(false);
		cal.set(Calendar.DAY_OF_MONTH,Integer.parseInt(date.substring(0,2)));
		cal.set(Calendar.MONTH, Integer.parseInt(date.substring(3,5))-1);
		cal.set(Calendar.YEAR, Integer.parseInt(date.substring(6,10)));
	
		try
		{
			cal.getTimeInMillis();
		}
		catch(Exception e)
		{
			return false; 
	    }
		return true;
	}
}
